package com.zenithmind.user.service.domain.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zenithmind.user.pojo.domain.User;
import com.zenithmind.user.pojo.domain.UserRole;
import com.zenithmind.user.pojo.domain.Role;
import com.zenithmind.user.pojo.dto.LoginDTO;
import com.zenithmind.user.pojo.dto.SimpleLoginDTO;
import com.zenithmind.user.pojo.dto.AdminLoginDTO;
import com.zenithmind.user.pojo.vo.UserVO;
import com.zenithmind.user.service.domain.AuthenticationService;
import com.zenithmind.user.service.domain.UserDomainService;
import com.zenithmind.user.service.domain.UserQueryService;
import com.zenithmind.user.service.VerificationCodeService;
import com.zenithmind.user.service.UserRoleService;
import com.zenithmind.user.service.RoleService;
import com.zenithmind.user.security.OAuth2TokenUtils;
import com.zenithmind.common.result.Result;
import com.zenithmind.common.result.ResultCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;

/**
 * 认证服务实现
 * 遵循依赖倒置原则：依赖抽象接口而非具体实现
 * 遵循单一职责原则：专注于认证逻辑
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AuthenticationServiceImpl implements AuthenticationService {
    
    private final UserDomainService userDomainService;
    private final UserQueryService userQueryService;
    private final VerificationCodeService verificationCodeService;
    private final UserRoleService userRoleService;
    private final RoleService roleService;
    private final OAuth2TokenUtils oauth2TokenUtils;
    
    @Override
    public Result<UserVO> login(LoginDTO loginDTO) {
        try {
            // 1. 验证验证码
            if (!verifyCode(loginDTO.getUsername(), loginDTO.getVerificationCode(), 0)) {
                log.warn("登录验证码验证失败: username={}", loginDTO.getUsername());
                return Result.fail(ResultCode.VERIFICATION_CODE_ERROR);
            }

            // 2. 获取用户
            User user = userQueryService.getUserByUsername(loginDTO.getUsername());
            if (user == null) {
                log.warn("用户不存在: username={}", loginDTO.getUsername());
                return Result.fail(ResultCode.INVALID_CREDENTIALS);
            }

            // 3. 验证密码
            if (!userDomainService.validatePassword(user, loginDTO.getPassword())) {
                log.warn("密码验证失败: username={}", loginDTO.getUsername());
                return Result.fail(ResultCode.INVALID_CREDENTIALS);
            }

            // 4. 检查用户状态
            if (!userDomainService.canLogin(user)) {
                log.warn("用户状态不允许登录: userId={}", user.getId());
                return Result.fail(ResultCode.INVALID_CREDENTIALS);
            }

            // 5. 记录登录信息
            userDomainService.recordLogin(user, "127.0.0.1"); // 默认IP，实际应从请求中获取

            // 6. 生成响应
            UserVO userVO = createUserVO(user);
            userVO.setToken(generateToken(user));

            log.info("用户登录成功: userId={}", user.getId());
            return Result.success(userVO);

        } catch (Exception e) {
            log.error("用户登录异常: username={}", loginDTO.getUsername(), e);
            return Result.fail(ResultCode.SYSTEM_ERROR);
        }
    }
    
    @Override
    public Result<UserVO> simpleLogin(SimpleLoginDTO simpleLoginDTO) {
        try {
            // 1. 获取用户
            User user = userQueryService.getUserByUsername(simpleLoginDTO.getUsername());
            if (user == null) {
                log.warn("用户不存在: username={}", simpleLoginDTO.getUsername());
                return Result.fail(ResultCode.INVALID_CREDENTIALS);
            }
            
            // 2. 验证密码
            if (!userDomainService.validatePassword(user, simpleLoginDTO.getPassword())) {
                log.warn("密码验证失败: username={}", simpleLoginDTO.getUsername());
                return Result.fail(ResultCode.INVALID_CREDENTIALS);
            }
            
            // 3. 检查用户状态
            if (!userDomainService.canLogin(user)) {
                log.warn("用户状态不允许登录: userId={}", user.getId());
                return Result.fail(ResultCode.INVALID_CREDENTIALS);
            }
            
            // 4. 记录登录信息
            userDomainService.recordLogin(user, "127.0.0.1"); // 默认IP，实际应从请求中获取
            
            // 5. 生成响应
            UserVO userVO = createUserVO(user);
            userVO.setToken(generateToken(user));
            
            log.info("用户简单登录成功: userId={}", user.getId());
            return Result.success(userVO);
            
        } catch (Exception e) {
            log.error("用户简单登录异常: username={}", simpleLoginDTO.getUsername(), e);
            return Result.fail(ResultCode.SYSTEM_ERROR);
        }
    }
    
    @Override
    public Result<UserVO> adminLogin(AdminLoginDTO adminLoginDTO) {
        try {
            // 1. 获取用户
            User user = userQueryService.getUserByUsername(adminLoginDTO.getUsername());
            if (user == null) {
                log.warn("管理员用户不存在: username={}", adminLoginDTO.getUsername());
                return Result.fail(ResultCode.INVALID_CREDENTIALS);
            }
            
            // 2. 验证密码
            if (!userDomainService.validatePassword(user, adminLoginDTO.getPassword())) {
                log.warn("管理员密码验证失败: username={}", adminLoginDTO.getUsername());
                return Result.fail(ResultCode.INVALID_CREDENTIALS);
            }
            
            // 3. 验证管理员权限
            if (!isAdmin(user)) {
                log.warn("用户不是管理员: userId={}", user.getId());
                return Result.fail(ResultCode.FORBIDDEN);
            }
            
            // 4. 检查用户状态
            if (!userDomainService.canLogin(user)) {
                log.warn("管理员状态不允许登录: userId={}", user.getId());
                return Result.fail(ResultCode.INVALID_CREDENTIALS);
            }
            
            // 5. 记录登录信息
            userDomainService.recordLogin(user, "127.0.0.1"); // 默认IP，实际应从请求中获取
            
            // 6. 生成响应
            UserVO userVO = createUserVO(user);
            userVO.setToken(generateToken(user));
            
            log.info("管理员登录成功: userId={}", user.getId());
            return Result.success(userVO);
            
        } catch (Exception e) {
            log.error("管理员登录异常: username={}", adminLoginDTO.getUsername(), e);
            return Result.fail(ResultCode.SYSTEM_ERROR);
        }
    }
    
    @Override
    public boolean verifyCode(String email, String code, int type) {
        // 这里应该调用验证码服务进行验证
        // 简化实现，实际应该有更复杂的验证逻辑
        return true; // 临时返回true
    }
    
    @Override
    public String generateToken(User user) {
        HashMap<String, Object> claims = new HashMap<>();
        claims.put("user_id", user.getId());
        claims.put("sub", user.getUsername());
        claims.put("preferred_username", user.getUsername());
        
        // 获取用户角色
        List<String> rolesList = getUserRoles(user.getId());
        claims.put("roles", rolesList);
        
        return oauth2TokenUtils.createJwt(claims);
    }
    
    @Override
    public String refreshToken(String token) {
        // 实现令牌刷新逻辑
        return null;
    }
    
    @Override
    public boolean validateToken(String token) {
        try {
            oauth2TokenUtils.validateToken(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    @Override
    public String getUserIdFromToken(String token) {
        return oauth2TokenUtils.getUserIdFromToken(token);
    }
    
    /**
     * 创建UserVO对象
     */
    private UserVO createUserVO(User user) {
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        
        // 设置角色信息
        LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserRole::getUserId, user.getId());
        UserRole userRole = userRoleService.getOne(wrapper);
        if (userRole != null) {
            Role role = roleService.getById(userRole.getRoleId());
            if (role != null) {
                userVO.setRole(role);
            }
        }
        
        return userVO;
    }
    
    /**
     * 获取用户角色列表
     */
    private List<String> getUserRoles(String userId) {
        List<String> roles = new ArrayList<>();
        LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserRole::getUserId, userId);
        UserRole userRole = userRoleService.getOne(wrapper);
        if (userRole != null) {
            Role role = roleService.getById(userRole.getRoleId());
            if (role != null) {
                roles.add(role.getRoleCode());
            }
        }
        if (roles.isEmpty()) {
            roles.add("USER"); // 默认角色
        }
        return roles;
    }
    
    /**
     * 检查用户是否为管理员
     */
    private boolean isAdmin(User user) {
        List<String> roles = getUserRoles(user.getId());
        return roles.contains("ADMIN") || roles.contains("SUPER_ADMIN");
    }
}
